﻿#region Copyright 
/*-------------------------------------------------------------------------
* 命名空间名称/文件名:    SSPivot.Admin.Core.Service.sys.OLLog/SysOptsServiceImpl 
* CLR版本:     4.0.30319.42000
* 机器名称:    DESKTOP-NHMLO8A
* 功 能：       N/A
* 类 名：       SysOptsServiceImpl
* 创建时间：  2025/6/4 15:57:12
* 版本号：      v1.0
* 创建人:        xulong
*-------------------------------------------------------------------------*/
#endregion
using IP2Region.Net.Abstractions;
using Mapster;
using MapsterMapper;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using SSPivot.Admin.Core.DbModel.sys;
using SSPivot.Admin.Core.Repository;
using SSPivot.Admin.Core.Service.sys.OLLog.Dto;
using SSPivot.AspNetCore.Services;
using SSPivot.Common;
using SSPivot.Common.Helpers;
using SSPivot.Tools.Config;
using SSPivot.Tools.Services.Tools.Dto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace SSPivot.Admin.Core.Service.sys.OLLog
{
    /// <summary>
    /// 操作日志服务
    /// </summary>
    public class SysOptsServiceImpl : ApplicationService, ISysOptsLogService
    {
        #region 接口注入
        public IHttpContextAccessor HttpContextAccessor { get; set; }
        public ISSPivotRepository<sys_opts_log> SysOptsLogRepository { get; set; }
        public Tools.Config.IP2RegionConfig IpConfig { get; set; }
        public SysOptsServiceImpl(IOptions<Tools.Config.IP2RegionConfig> ipConfig,
            IHttpContextAccessor httpContextAccessor,
            ISSPivotRepository<sys_opts_log> reps)
        {
            IpConfig = ipConfig.Value;
            HttpContextAccessor = httpContextAccessor;
            SysOptsLogRepository = reps;
        }
        #endregion
        #region 服务

        /// <summary>
        /// 获得IP地址
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        private BaseLocationInfo GetIpLocationInfo(string ip)
        {
            var locationInfo = new BaseLocationInfo();
            if (IpConfig.Enabled)
            {
                var region = AppDependencyResolver.Current.GetScopeService<ISearcher>().Search(ip);
                locationInfo = BaseLocationInfo.Parse(region);
            }
            return locationInfo;
        }

        /// <summary>
        /// 查询分页
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns> 
        public async Task<(List<SysOptsLogDto>, PageResult)> PageAsync(QuerySysOptsLogRequest model, PageResult page)
        {
            var data = await SysOptsLogRepository.QueryNoTracking(this.BuildSearch(model), this.BuildSort(model), page).ToListAsync();
            return (data.Adapt<List<SysOptsLogDto>>(), page);
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<long> AddAsync(SysOptsLogDto input)
        {
            string ua = HttpContextAccessor.HttpContext.Request.Headers["User-Agent"];
            if (ua.IsNotNullOrEmpty())
            {
                var client = UAParser.Parser.GetDefault().Parse(ua);
                var device = client.Device.Family;
                device = device.ToLower() == "other" ? "" : device;
                input.Browser = client.UA.Family;
                input.Os = client.OS.Family;
                input.Device = device;
                input.BrowserInfo = ua;
            }
            input.Name = User.Name;

            var entity = Mapper.Map<sys_opts_log>(input);

            if (entity.IP.IsNull())
            {
                entity.IP = ServerRequestHelper.GetRemoteIP();
                var locationInfo = GetIpLocationInfo(entity.IP);
                entity.Country = locationInfo?.Country;
                entity.Province = locationInfo?.Province;
                entity.City = locationInfo?.City;
                entity.Isp = locationInfo?.Isp;
            }

            await SysOptsLogRepository.AddAsync(entity);

            return entity.Id;
        }
        #endregion

        #region private
        private Expression<Func<sys_opts_log, bool>> BuildSearch(QuerySysOptsLogRequest model)
        {
            Expression<Func<sys_opts_log, bool>> whereCondition = e => true;

            if (model.Creator.IsNotNullOrWhiteSpace())
                whereCondition = whereCondition.And(e => e.Creator.Contains(model.Creator));
            if (model.Status.HasValue)
                whereCondition = whereCondition.And(x => x.Status == model.Status);
            if (model.IP.IsNotNullOrWhiteSpace())
                whereCondition = whereCondition.And(e => e.IP.Contains(model.IP));
            if (model.SDate.HasValue)
                whereCondition = whereCondition.And(e => e.CreatedTime > model.SDate);
            if (model.Api.IsNotNullOrWhiteSpace())
                whereCondition = whereCondition.And(e => e.ApiLabel.Contains(model.Api) || e.ApiPath.Contains(model.Api));
            if (model.EDate.HasValue)
            {
                var date = model.EDate.Value.AddDays(1);
                whereCondition = whereCondition.And(e => e.CreatedTime < date);
            }

            return whereCondition;
        }

        private Dictionary<Expression<Func<sys_opts_log, dynamic>>, SortType> BuildSort(QuerySysOptsLogRequest model)
        {
            var orderBy = new Dictionary<Expression<Func<sys_opts_log, dynamic>>, SortType>();

            orderBy.Add(e => e.Id, SortType.Desc);
            return orderBy;
        }

        #endregion
    }
}

